iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
DevOps

DevOps菜鳥的30天實踐挑戰:從 CI/CD Pipeline 到雲端佈署系列 第 7

Day07 - 使用 YAML 定義 Pipeline: 條件邏輯與變數的應用

  • 分享至 

  • xImage
  •  

在今天的文章中,我們將深入探討如何在 YAML 文件中應用條件邏輯變數,來實現更靈活且可擴展的 CI/CD 流程。隨著專案複雜度增加,僅依賴基礎的 YAML 設定可能無法滿足多環境、跨平台或動態調整的需求,因此,我們可以藉助條件語句與變數,來創建可根據需求進行靈活配置的Pipeline。


什麼是 YAML?

YAML (YAML Ain't a Markup Language / Yet Another Markup Language) 是一種輕量級、可讀性高的資料格式,非常適合用來定義 CI/CD Pipelines。它以簡潔的語法,能夠幫助團隊更快地管理和佈署應用程式。尤其在 DevOps 實踐中,YAML 是定義自動化流程的首選格式之一。

YAML-based Pipeline 的配置方式,讓我們能夠靈活地定義 CI/CD 工作流程,並且完全由程式碼控制。可以輕鬆地集成版本控制,從而提升可維護性和透明度。

YAML 文件格式簡單易懂,具有以下幾個特點:

  1. 縮排敏感:層次結構由縮排來決定,不同層級以空格縮排表示。
  2. 鍵值對結構:使用鍵值對(Key-value pairs)的方式來表示數據,非常直觀。
  3. 易於維護:簡潔的語法讓文件易於閱讀和管理,尤其適合長期使用和維護。

為什麼使用 YAML 定義 Pipeline?

  1. 程式碼即配置:YAML 定義的 Pipeline 可以與應用程式的程式碼一起進行版本控制,方便追蹤歷史變更。
  2. 可重複性:YAML 文件可定義標準的自動化流程,能輕鬆複製到其他專案中,提升開發效率。
  3. 高可讀性:其簡單的結構讓團隊成員能夠快速理解與修改 Pipeline 配置。
  4. 高擴展性:YAML 支援條件式執行,能夠靈活應對不同的開發需求。

YAML 配置

條件邏輯 (Conditional Logic)

條件邏輯允許我們根據某些條件(例如分支、變數值或其他環境參數)來決定是否執行某些步驟。這對於多環境佈署、多階段測試或跨平台應用程式開發尤為重要。

在 Azure Pipelines 的 YAML 文件中,我們可以使用 condition 關鍵字來設定條件,這些條件可以基於 pipeline 執行時的上下文,例如分支名稱、構建狀態、變數值等。

示例:針對不同的分支執行不同的步驟

steps:
- script: echo "This runs on all branches."
  displayName: 'Run on all branches'  # 此步驟會在所有分支上執行

- script: echo "This runs only on the main branch."
  displayName: 'Run on main branch only'  # 這一步驟僅在 main 分支執行
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')  # 使用條件邏輯檢查當前分支是否為 main 分支

- script: echo "This runs only on feature branches."
  displayName: 'Run on feature branches'  # 這一步驟僅在 feature 分支執行
  condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/feature/')  # 使用條件邏輯檢查當前分支是否為 feature 分支

在這個範例中,根據當前構建的分支不同,會有不同的指令被執行。當應用於多環境或多分支開發時,條件邏輯能夠幫助 CI/CD 流程更加自動化。


變數 (Variables)

變數是一種強大的工具,可以讓我們在 YAML Pipeline中輕鬆重複使用值,避免在不同步驟中重複定義相同內容。Azure Pipelines 支持多種類型的變數,包括全域變數、區域變數,甚至可以從外部服務(如 Azure Key Vault)提取機密變數。

機密變數 (Secret Variables)

如果我們的應用需要使用敏感資訊(如 API 密鑰、資料庫連接字串),可以將這些變數設置為「機密變數」,並透過 Azure Key Vault 等秘鑰管理工具來保護這些資訊。這樣可以確保敏感資料不會直接暴露在 YAML 文件中。

基本變數示例:

variables:
  pythonVersion: '3.9'  # 定義 Python 版本號
  projectName: 'MyApp'  # 定義專案名稱

steps:
- script: echo "Building $(projectName) using Python $(pythonVersion)"
  displayName: 'Display Project and Python Version'  # 顯示專案名稱和 Python 版本

- script: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
  displayName: 'Install dependencies for $(projectName)'  # 安裝專案所需的依賴包

在這個例子中,我們定義了 pythonVersionprojectName 兩個變數,然後在不同的步驟中使用它們。這樣可以提高可讀性,並且未來修改變數時,只需改動一處即可。


使用條件邏輯與變數實現靈活的 CI/CD

現在我們將結合條件邏輯與變數,展示一個更實際的 CI/CD Pipeline示例。在這個示例中,我們將根據分支名稱來自動化佈署應用程式至不同的環境,並使用變數來設定不同的環境配置。

示例:基於分支進行環境佈署

variables:
  devEnvName: 'dev-environment'  # 定義開發環境的名稱
  prodEnvName: 'prod-environment'  # 定義正式環境的名稱
  containerRegistry: 'myDockerRegistry'  # 定義容器註冊表
  repository: 'myDockerRepo/myApp'  # 定義容器庫的存儲庫名稱

stages:
- stage: Build
  jobs:
  - job: BuildApp
    pool:
      vmImage: 'ubuntu-latest'  # 指定構建作業使用的虛擬機映像
    steps:
    - script: echo "Building the application..."
      displayName: 'Build the app'  # 顯示正在構建應用程式

    - task: Docker@2
      inputs:
        containerRegistry: $(containerRegistry)  # 從變數中取得容器註冊表
        repository: $(repository)  # 從變數中取得容器庫存儲庫
        command: build  # 執行 Docker 的構建指令
        Dockerfile: '$(Build.SourcesDirectory)/Dockerfile'  # 指定 Dockerfile 的位置
        tags: |
          $(Build.BuildId)  # 使用構建 ID 作為標籤

- stage: DeployToDev
  dependsOn: Build  # 此階段依賴於 Build 階段
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/develop')  # 僅在 develop 分支執行此佈署步驟
  jobs:
  - job: DeployToDev
    steps:
    - script: echo "Deploying to $(devEnvName)"
      displayName: 'Deploy to Development Environment'  # 顯示正在佈署到開發環境

- stage: DeployToProd
  dependsOn: Build  # 此階段依賴於 Build 階段
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')  # 僅在 main 分支執行此佈署步驟
  jobs:
  - job: DeployToProd
    steps:
    - script: echo "Deploying to $(prodEnvName)"
      displayName: 'Deploy to Production Environment'  # 顯示正在佈署到正式環境

在這個例子中,我們定義了兩個佈署階段(DeployToDevDeployToProd),根據當前的分支是否為 developmain 來決定佈署的環境。此外,我們還使用了變數來定義環境名稱與容器庫地址,這樣讓Pipeline的配置更加靈活。


Pipeline 中的全域變數與模板

隨著專案規模的擴大,可能會出現多個Pipeline 共用同樣的步驟或配置。這時候我們可以使用模板 (templates) 來將重複的部分抽取出來,提升Pipeline的可重用性。

示例:提取模板

首先,創建一個模板檔案 build-template.yml

parameters:
  - name: pythonVersion
    type: string
    default: '3.9'  # 定義模板的參數,預設 Python 版本為 3.9

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: ${{ parameters.pythonVersion }}  # 使用模板參數來指定 Python 版本
  displayName: 'Use Python ${{ parameters.pythonVersion }}'  # 顯示使用的 Python 版本

- script: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
  displayName: 'Install dependencies'  # 安裝依賴

然後,在主 YAML 文件中引用這個模板:

stages:
- stage: Build
  jobs:
  - job: BuildApp
    pool:
      vmImage: 'ubuntu-latest'  # 使用 Ubuntu 最新的虛擬機映像進行構建
    steps:
    - template: build-template.yml
      parameters:
        pythonVersion: '3.10'  # 使用模板並指定 Python 版本為 3.10

這樣我們可以簡化主 YAML 文件的內容,並通過模板來管理重複的構建步驟。


結論

今天我們深入探討了如何在 YAML 文件中使用條件邏輯與變數來實現靈活的 CI/CD 流程。透過這些進階技術,能夠根據實際需求動態配置Pipeline,並減少重複性配置,提升專案的可維護性。隨著專案的擴展,會發現這些技巧可以讓我們的 CI/CD 流程變得更加智慧與高效!

文章的最後,再次提醒大家,YAML對縮排是相當敏感的,佈署至正式環境前,謹慎檢查啊~~~。゚ヽ(゚´Д`)ノ゚。
https://ithelp.ithome.com.tw/upload/images/20240921/20169492BsUPsWNCWE.jpg
圖片來源

預告

明天我們將進入容器(Container)的世界,介紹容器化技術(Containerization)如何改變應用程式的開發與佈署流程。我們將學習 Docker 的基礎概念,並理解如何將 Docker 與 CI/CD 管道整合,實現更加靈活且可靠的佈署策略~


參考文件

https://www.redhat.com/en/topics/automation/what-is-yaml

https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started

https://www.commonwl.org/user_guide/topics/yaml-guide.html

https://yaml.irz.fr/key-value-pairs.html

https://www.runoob.com/w3cnote/yaml-intro.html


上一篇
Day06 - 使用 Azure DevOps Pipelines 持續交付 (CD)
下一篇
Day08 - Docker 簡介與容器化概念
系列文
DevOps菜鳥的30天實踐挑戰:從 CI/CD Pipeline 到雲端佈署30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言